﻿//Copyright (C) <2013> jonathan cleeve norton website http://www.fin-plus.co.uk
using System;
using System.Linq;
using System.Reflection;
using System.Net;
using FinPlusCompCore;
using FinPlusAssembler;
using FinPlusInterfaces;

namespace FinPlusCompFeeds
{
    public class FinPlusGoogleFeed : FinPlusComponent
    {
        [State(Test = true)]
        public override bool IsValid { get; set; }
        [State(Test = true)]
        public override string TestString { get { return Adapter.ToString(); } }
        public override IPods Adapter { get { return _adapter; } }
   
        private enum parms { PxHistory, Exchange, Ticker, Info, Feed }
        private readonly IPods _adapter;
        private readonly string[] _tickers, _columns;
        private readonly string _url, _dateTimeFormat;
        private int _Id;
        private Env _env;

        //construct
        public FinPlusGoogleFeed(string tickers, string columns, string period, string days, string dateTimeFormat)
        {
            _adapter = IOC.New<IPods>();
            _tickers = tickers.Split();
            _columns = columns.Split('|');
            _dateTimeFormat = dateTimeFormat;

            var config = Assembly.GetExecutingAssembly().ConfigPath().ConfigXml(out _env);
            _url = config["feeds"]["google"].Replace("[period]", period).Replace("[days]", days);
           
            GetTickers();
        }

        //common control interface
        public override void Dispose(){ }

        //private
        private void GetTickers()
        {
            foreach(var ticker in _tickers)
                 GetTicker(ticker);
        }

        private void GetTicker(string ticker)
        {
            using (var google = new WebClient())
            {
                var res = google.DownloadString(_url.Replace("[ticker]", ticker)).ToJaggedArray();
                var colList = res[4];

                if(!string.IsNullOrEmpty(_dateTimeFormat))
                    AddDateTime(ticker, res, int.Parse(res[1][0].Split('=')[1]), int.Parse(res[3][0].Split('=')[1]));

                foreach (var column in _columns)
                    AddColumn(ticker, res, column, Array.FindIndex(colList, c => c == column));
            }
        }

        private void AddDateTime(string ticker, string[][] res, int openMin, int interval)
        {
            if (string.IsNullOrEmpty(_dateTimeFormat))
                return; 

            var pod = IOC.New<IPod>(parms.PxHistory.ToString(), _Id.ToString(), parms.Feed.ToString(), ++_Id);
            pod.Add(parms.Exchange.ToString(), res[0][0].Split('%')[1]);
            pod.Add(parms.Ticker.ToString(), ticker);
            pod.Add(parms.Info.ToString(), "DATETIME");

            var datetime = DateTime.MinValue;

            for (var row = 7; row < res.Count() - 1; row++)
            {
                if (res[row][0].StartsWith("a"))
                {
                    datetime = DateTime.FromOADate(int.Parse(res[row][0].TrimStart('a')) / 86400 + 25569 + (5.5 / 24)).AddMinutes(openMin);
                    res[row][0] = "0";
                    pod.Add(res[row][0], datetime.ToString(_dateTimeFormat));
                }
                else
                    pod.Add(res[row][0], datetime.AddSeconds(int.Parse(res[row][0]) * interval).ToString(_dateTimeFormat));
            }

            _adapter.Add(pod);
        }

        private void AddColumn(string ticker, string[][] res, string column, int col)
        {
            var pod = IOC.New <IPod>(parms.PxHistory.ToString(), _Id.ToString(), parms.Feed.ToString(), ++_Id);
            pod.Add(parms.Exchange.ToString(), res[0][0].Split('%')[1]);
            pod.Add(parms.Ticker.ToString(), ticker);
            pod.Add(parms.Info.ToString(), column);

            for (var row = 7; row < res.Count() - 1; row++)
                pod.Add(res[row][0], res[row][col]);

            _adapter.Add(pod);
        }
    }
}
